/*
 * @Author: 李石
 * @Date: 2024-05-18 21:00:19
 * @LastEditors: lishi
 * @LastEditTime: 2024-05-24 14:33:42
 * @Description: 
 * Copyright (c) 2024 by ${lishi0105@163.com}, All Rights Reserved. 
 */
#include "HttpServer.hpp"
#include "logger.hpp"

void HttpServer::EventHandler(struct mg_connection* connection, int event, void* event_data)
{
    if(connection == nullptr){
        return;
    }
    if (event == MG_EV_HTTP_MSG) {
        struct mg_http_message* hm = (struct mg_http_message*) event_data;
        HttpServer* server = static_cast<HttpServer*>(connection->fn_data);
        if(server){
            server->Handle(std::string(hm->uri.buf, hm->uri.len), connection, hm);
        }
    }
}

HttpServer::HttpServer(int port) : 
    port_(port) , running_(false) 
{
    mg_mgr_init(&mgr_);
    char listen_url[128] = {0};
    snprintf(listen_url, sizeof(listen_url), "http://0.0.0.0:%d", port_);
    LOGI("listen_url: {}", listen_url);
    connection_ = mg_http_listen(&mgr_, listen_url, HttpServer::EventHandler, nullptr); // Add the missing event_handler parameter
    if (connection_ == nullptr) {
        throw std::runtime_error("Failed to create listener");
    }
    connection_->fn_data = this;
    data_handler_ = HttpDataHandler::CreateShared();
    if(data_handler_ == nullptr){
        throw std::runtime_error("data_handler_ is nullptr");
    }
    handlers_["/index/api/addstreamproxy"] = 
            std::bind(&HttpDataHandler::HandleAddStreamProxy, data_handler_, std::placeholders::_1, std::placeholders::_2);
    handlers_["/index/api/getstreamlist"] = 
            std::bind(&HttpDataHandler::HandleGetStreamList, data_handler_, std::placeholders::_1, std::placeholders::_2);
    handlers_["/index/api/getstreaminfo"] = 
            std::bind(&HttpDataHandler::HandleGetStreamInfo, data_handler_, std::placeholders::_1, std::placeholders::_2);
    handlers_["/index/api/deletestreamproxy"] = 
            std::bind(&HttpDataHandler::HandleDeleteStreamProxy, data_handler_, std::placeholders::_1, std::placeholders::_2);
}

HttpServer::~HttpServer() 
{
    Stop();
    mg_mgr_free(&mgr_);
    LOGI("HttpServer::~HttpServer");
}

void HttpServer::Start() {
    if (!running_.load()) {
        running_ = true;
        data_handler_->init();
        std::thread(&HttpServer::Run, this).detach();  // Detach the thread
    }
}

void HttpServer::Stop() {
    if (running_.load()) {
        running_.store(false);
    }
    LOGI("HttpServer::Stop");
}

void HttpServer::Run() 
{
    while (running_.load())
    {
        mg_mgr_poll(&mgr_, 500);
    }
}

void HttpServer::Handle(std::string uri, struct mg_connection* connection, struct mg_http_message* hm)
{
    if(handlers_.find(uri) != handlers_.end()){
        handlers_[uri](connection, hm);
    }else{
        data_handler_->HandleNotFound(connection, nullptr);
    }
}